﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Net;
using System.Net.Mail;
using ItalcoTransfer.italco.utils;

namespace ItalcoTransfer.italco.vo
{
    public class HyperFileVO
    {
        #region Variables privadas
        private List<EmployeeVO> _employees;
        private List<EmployeeVO> _employeesXML;
        private string _Separador;
        //private string _Email_aviso_ERROR;
        //private string _Email_aviso_OK;
        ////private string _Remitente_Email_aviso;
        private string _Mascara_entrada;
        private string _Mascara_salida;
        private string _Ruta_entrada;
        private string _Ruta_BackUps;
        private string _Ruta_salida;
        //private string _Servidor_SMTP;
        private bool _Utilizar_separador;
        private string _sTipoFichero;
        private string _sNombreFichero;
        private bool _bHasData;
        private int _iNumeroLineasArchivo;
        private int _iProcesadosKO;
        //private string _rutaFicheroPeriodo;
        //private int _iNumeroLineasFueraPeriodo;
        
        
        #endregion

        public HyperFileVO()
        {
            HasErrors = false;
            Errores = new List<ErrorInfo>();
            _employees = new List<EmployeeVO>();
            _employeesXML = new List<EmployeeVO>();
        }
        public HyperFileVO(HyperFileVO inValue)
        {
            _employees = new List<EmployeeVO>();
            _employeesXML = new List<EmployeeVO>();
            this.Employees = new List<EmployeeVO>();
            this.EmployeesXML = new List<EmployeeVO>();
            this.Mascara_entrada = inValue.Mascara_entrada;
            this.Mascara_salida = inValue.Mascara_salida;
            this.Ruta_entrada = inValue.Ruta_entrada;
            this.Ruta_salida = inValue.Ruta_salida;
            this.Separador = inValue.Separador;           
            this.Tipo_Fichero = inValue.Tipo_Fichero; 
            this.Utilizar_separador = inValue.Utilizar_separador;
            this.Ruta_BackUps = inValue.Ruta_BackUps;
            this.NombreFichero = inValue.NombreFichero;

            HasErrors = false;
            Errores = new List<ErrorInfo>();
        }

        ~HyperFileVO()
        {
            Errores = null;
            _employees = null;
        }

        public List<ErrorInfo> Errores;
        public bool HasErrors;

        #region Propiedades
        //public int SMTP_Port{ get; set; }
        //public string SMTP_User {get; set;}
        //public string SMTP_Password {get; set;}
        public List<EmployeeVO> Employees
        {
            get
            {
                return _employees;
            }
            set
            {
                _employees = value;
            }
        }
        public List<EmployeeVO> EmployeesXML
        {
            get
            {
                return _employeesXML;
            }
            set
            {
                _employeesXML = value;
            }
        }
        public string Separador
        {
            get { return _Separador; }
            set { _Separador = value; }
        }
        public string NombreFichero
        {
            get { return _sNombreFichero; }
            set { _sNombreFichero = value; }
        }
        //public string Email_aviso_ERROR
        //{
        //    get{return _Email_aviso_ERROR;}
        //    set { _Email_aviso_ERROR= value; }
        //}
        //public string Email_aviso_OK
        //{
        //    get { return _Email_aviso_OK; }
        //    set { _Email_aviso_OK = value; }
        //}
        public string Mascara_entrada
        {
            get { return _Mascara_entrada; }
            set { _Mascara_entrada = value; }
        }
        public string Mascara_salida
        {
            get { return _Mascara_salida; }
            set { _Mascara_salida = value; }
        }
        public string Ruta_entrada
        {
            get { return _Ruta_entrada; }
            set { _Ruta_entrada = value; }
        }
        public string Ruta_salida
        {
            get { return _Ruta_salida; }
            set { _Ruta_salida = value; }
        }
        public string Ruta_BackUps
        {
            get { return _Ruta_BackUps; }
            set { _Ruta_BackUps = value; }
        }
        //public string Servidor_SMTP
        //{
        //    get { return _Servidor_SMTP; }
        //    set { _Servidor_SMTP = value; }
        //}
        public bool HasData
        {
            get { return _bHasData; }
            set { _bHasData = value; }
        }
        public bool Utilizar_separador
        {
            get { return _Utilizar_separador; }
            set { _Utilizar_separador = value; }
        }
        public string Tipo_Fichero
        {
            get { return _sTipoFichero; }
            set { _sTipoFichero = value; }
        }
        public int NumeroLineasArchivo
        {
            get
            {
                return _iNumeroLineasArchivo;
            }
            set
            {
                _iNumeroLineasArchivo = value;
            }
        }
        //public int NumeroLineasFueraPeriodo
        //{
        //    get
        //    {
        //        return _iNumeroLineasFueraPeriodo;
        //    }
        //    set
        //    {
        //        _iNumeroLineasFueraPeriodo = value;
        //    }
        //}
        public int NumeroProcesadosKO
        {
            get
            {
                return _iProcesadosKO;
            }
            set
            {
                _iProcesadosKO = value;
            }
        }
        //public string RutaFicheroPeriodo
        //{
        //    get { return _rutaFicheroPeriodo; }
        //    set { _rutaFicheroPeriodo = value; }
        //}
        #endregion

        #region Methods
        public bool AddEmployee(EmployeeVO employee)
        {
            //if (_employees.Where(x => x.Numero == employee.Numero 
            //                        && x.ActionType == employee.ActionType
            //                    ).Count() == 0)
            //{
                //Añadir código para tratar el tema de los hijos/relatives
                if (employee!=null)
                    _employees.Add(employee);
                return true;
            //}
            //else
            //    return false;
        }

        //public string Remitente_Email_aviso
        //{ get;set; }

        public void GenerateXML()
        {
            string sTexto = "";
            string sRuta = this.Ruta_salida + string.Format(this.Mascara_salida, DateTime.Now.ToString("yyyyMMdd_HHmmssff"));
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(sRuta, false, Encoding.Default))
            {
                sw.Write(Resources.TextosTraduccionXML.TraduccionFile_Cabecera + "\n");
                sw.Write(Resources.TextosTraduccionXML.TraduccionEmpleados_Cabecera + "\n");
                foreach (EmployeeVO oEmployee in Employees)
                {
                    sTexto = oEmployee.GenerateXML(ref this.Errores);
                    if (sTexto != "")
                    {
                        sw.Write(sTexto);
                    }
                }

                sw.Write(Resources.TextosTraduccionXML.TraduccionEmpleados_Pie + "\n");
            }
        }

        //public void GenerateXML()
        //{
        //    string sTexto = "";
        //    string sRuta = this.Ruta_salida + string.Format(this.Mascara_salida, DateTime.Now.ToString("yyyyMMdd_HHmmssff"));
        //    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(sRuta,false,  Encoding.Default))
        //    {
        //        sw.Write(Resources.TextosTraduccionXML.TraduccionFile_Cabecera + "\n");
        //        sw.Write(Resources.TextosTraduccionXML.TraduccionEmpleados_Cabecera + "\n");

        //        EmployeesXML.Add(Employees[0]);
        //        //CASUISTICAS
        //        for (int i = 1; i < Employees.Count; i++)
        //        {
        //            EmployeeVO oEmployee = Employees[i];
        //                //Recorrer los anteriores
        //                for (int j = 0; j < i; j++)
        //                {
        //                    if (Employees[i].Numero == Employees[j].Numero)
        //                    {
        //                        //Casuisticas
        //                        //Si recibimos una modificación, comprobamos si antes tenemos un Alta del mismo empleado
        //                        if (Employees[i].TipoRegistro == enums.enumTipoRegistro.Modificacion)
        //                        {
        //                            if (Employees[j].TipoRegistro == enums.enumTipoRegistro.Alta)
        //                            {
        //                                //No generamos nuevo campo EMPLEADO, sino modificamos valores de oEmployee dependiendo del Event_Type
        //                                Employees[i].ChangeFieldsValues(Employees[j]);
                                        
        //                                if(!EmployeesXML.Contains(Employees[j]))
        //                                    EmployeesXML.Add(Employees[j]);
        //                            }
        //                        }
        //                        //No podemos tener Alta y Baja de un mismo Empleado en el mismo xml de salida
        //                        else if (((Employees[i].TipoRegistro == enums.enumTipoRegistro.Baja) && (Employees[j].TipoRegistro == enums.enumTipoRegistro.Alta))
        //                            || ((Employees[i].TipoRegistro == enums.enumTipoRegistro.Alta && Employees[j].TipoRegistro == enums.enumTipoRegistro.Baja)))
        //                        {
        //                            //Generar nuevo HyperFileVO
        //                        }
        //                        else
        //                        {
        //                            EmployeesXML.Add(oEmployee);
        //                        }

        //                    }
        //                    //Si es Empleado con numero diferente, generemos xml
        //                    else                            
        //                        EmployeesXML.Add(oEmployee);                                
                            
        //                }
                    
                    
                  
        //        }

        //        foreach (EmployeeVO empl in EmployeesXML)
        //        {
        //            sTexto = empl.GenerateXML(ref this.Errores);
        //            if (sTexto != "")
        //            {
        //                sw.Write(sTexto);
        //            }
        //        }

               
        //        sw.Write(Resources.TextosTraduccionXML.TraduccionEmpleados_Pie + "\n");
        //    }            
        //}

        public void MoveFileOK()
        {
            if (Ruta_salida != "" && Ruta_entrada != "")
            {
                if (System.IO.File.Exists(this._sNombreFichero))
                {                    
                    string[] sRuta = _sNombreFichero.Split(char.Parse(@"\"));
                    string sRutabackUp = Ruta_BackUps.TrimEnd(char.Parse(@"\")) + @"\OK\";
                    System.IO.Directory.CreateDirectory(sRutabackUp);
                    string sRutabackUpCompleta = sRutabackUp + sRuta[sRuta.Length - 1];
                    if (System.IO.File.Exists(sRutabackUpCompleta))
                        sRutabackUpCompleta = sRutabackUp + DateTime.Now.ToString("yyyyMMddHHmmssff") + "_" + sRuta[sRuta.Length - 1];
                    System.IO.File.Move(_sNombreFichero, sRutabackUpCompleta);
                }
            }
        }
        public void MoveFileKO()
        {
            if (Ruta_salida != "" && Ruta_entrada != "")
            {
                if (System.IO.File.Exists(this._sNombreFichero))
                {
                    string[] sRuta = _sNombreFichero.Split(char.Parse(@"\"));
                    string sRutabackUp = Ruta_BackUps.TrimEnd(char.Parse(@"\")) + @"\KO\";
                    System.IO.Directory.CreateDirectory(sRutabackUp);
                    string sRutabackUpCompleta = sRutabackUp + sRuta[sRuta.Length - 1];
                    if (System.IO.File.Exists(sRutabackUpCompleta))
                        sRutabackUpCompleta = sRutabackUp + DateTime.Now.ToString("yyyyMMddHHmmssff") + "_" + sRuta[sRuta.Length - 1];
                    System.IO.File.Move(_sNombreFichero, sRutabackUpCompleta);
                }
            }
        }
        public HyperFileVO Fill(string sFile)
        {
            HyperFileVO Result = new HyperFileVO(this);
            Result.HasData = false;

            //string sPeriodoActivo = DateTime.Today.ToString("yyyyMM");

            //if (this.RutaFicheroPeriodo != "" && System.IO.File.Exists(this.RutaFicheroPeriodo))
            //{
            //    //El fichero deberá existir, y contener una sola linea en el formato MMYYYY
            //    sPeriodoActivo = System.IO.File.OpenText(this.RutaFicheroPeriodo).ReadToEnd();
            //    if (sPeriodoActivo.Length > 6) sPeriodoActivo = sPeriodoActivo.Substring(0, 6);
            //    sPeriodoActivo = sPeriodoActivo.Substring(2, 4) + sPeriodoActivo.Substring(0, 2);
            //}
            //int iPeriodoActivo = int.Parse(sPeriodoActivo);
            //string[] sFiles = System.IO.Directory.GetFiles(this.Ruta_entrada, this.Mascara_entrada);
            //foreach (string sFile in sFiles)
            //{
                ErrorInfo errorInfo = new ErrorInfo();
                string sFileKO = sFile + "_KO";
                Result.NombreFichero = sFile;
                Result.NumeroProcesadosKO = 0;
                Result.NumeroLineasArchivo = 0;
                string sRutaError=
                    this.Ruta_salida + "ERROR\\KO_" + 
                    sFile.Split(char.Parse("\\"))[sFile.Split(char.Parse("\\")).Length-1];
                if (!System.IO.Directory.Exists(this.Ruta_salida + "ERROR"))
                    System.IO.Directory.CreateDirectory(this.Ruta_salida + "ERROR");
                List<string> sRegistrosError = new List<string>();
                if (!System.IO.File.Exists(sFile))
                {
                    Result.HasErrors = true;                        
                    Result.Errores.Add(new  ErrorInfo(string.Format(Resources.TextosError.Error_FicheroBloqueado, sFile),""));
                    throw new italco.utils.TransferException(errorInfo.ErrorDescription);
                }
                //using (System.IO.StreamReader sr = System.IO.File.OpenText(sFile))
                //{
                    //String input;
                    bool bPrimeraFila = true;
                    string sLastID = "", sLastPeriodo = "";
                    EmployeeVO empResul;

                    string[] sLineas = System.IO.File.ReadAllLines(sFile, Encoding.Default);                                      
                    //int iLastPeriodo = 0;
                    foreach(string input in sLineas)
                    {
                        if (input.Trim() != "" && input.IndexOf(";")>0)
                        {
                            if (bPrimeraFila)
                            {
                                bPrimeraFila = false;
                            }
                            //else
                            //{
                            //    //CASUISTICAS
                            //    for (int i = 1; i <= sLineas.Count(); i++)
                            //    {
                            //        for (int j = 0; j < i; j++)
                            //        {
                                        
                            //        }
                            //    }

                            //}                           
                            Result.NumeroLineasArchivo++;
                            string[] sCampos = input.Split(char.Parse(this.Separador));
                                
                            
                            foreach (EmployeeVO emp in this.Employees)
                            {
                                int iNumErrores = Result.Errores.Count;
                                empResul = emp.FillFromTXT(sCampos, sLastID, sLastPeriodo, ref Result);
                                //Peticion 
                                //if (empResul != null && empResul.Periodo!="") iLastPeriodo = int.Parse(empResul.Periodo);
                                //if (iPeriodoActivo <= iLastPeriodo)
                                //{                                       
                                    if (iNumErrores != Result.Errores.Count)
                                    {
                                        Result.NumeroProcesadosKO++;
                                        Result.HasErrors = true;
                                        //No se ha cargado el registro... guardamos BackUp de la linea
                                        sRegistrosError.Add(input);
                                    }
                                    else
                                    {                                        
                                        Result.HasData = true;
                                        Result.AddEmployee(empResul);
                                        if (empResul != null)
                                        {
                                            sLastID = empResul.Numero;
                                            //sLastPeriodo = empResul.Periodo;
                                        }
                                    }
                                //}
                                //else
                                //{
                                //    //Result.NumeroLineasFueraPeriodo++;
                                //}
                                   
                            }
                            
                        }
                    }
                //}
                if (sRegistrosError.Count() > 0)
                {
                    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(sRutaError))
                    {
                        foreach (string sError in sRegistrosError)
                        {
                            sw.WriteLine(sError);
                        }
                    }
                }
            //}
            return Result;
        }

        private void SendMail( string smtp, string username, string password, int port, string email_address_TO, string email_address_FROM, string subject, string body)
        {
            MailMessage msg = new MailMessage();


            msg.To.Add(new MailAddress(email_address_TO));
            msg.From = new MailAddress(email_address_FROM);
            msg.Subject = subject;
            msg.Body = body;

            SmtpClient server = new SmtpClient(smtp);
            server.Timeout = 100000;
            server.DeliveryMethod = SmtpDeliveryMethod.Network;
            server.UseDefaultCredentials = false;
            if (username != "" && password != "")
                server.Credentials = new NetworkCredential(username, password);
 
            try
            {
                server.Send(msg);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                //LogFile.LogERROR(ex.Message);                
            }
        }
        //public void EnviarCorreoError()
        //{
        //    string sTexto;
        //    sTexto = string.Format(Resources.TextosProceso.Email_Texto_Nombre_Fichero + "\n", this.NombreFichero);
        //    sTexto += string.Format(Resources.TextosProceso.Email_Texto_Registros_Procesados_Correctamente_2Param + "\n", this.NumeroLineasArchivo - this.NumeroProcesadosKO, this.NumeroLineasFueraPeriodo);
        //    sTexto += string.Format(Resources.TextosProceso.Email_Texto_Registros_Procesados_Error_1Param + "\n", this.NumeroProcesadosKO);
        //    sTexto += Resources.TextosProceso.Email_Texto_Error;
        //    foreach (ErrorInfo errInfo in this.Errores)
        //    {
        //        sTexto += errInfo.ErrorDescription + "\n";
        //    }

        //    if (this.Servidor_SMTP != "" && this.Email_aviso_ERROR != "")
        //    {
        //        SendMail(Servidor_SMTP, SMTP_User, SMTP_Password, SMTP_Port, Email_aviso_ERROR, Remitente_Email_aviso, "Se produjo un error en la interfase", sTexto);
        //    }
        //}
        //public void EnviarCorreoOK()
        //{
        //    string sTexto = string.Format(Resources.TextosProceso.Email_Texto_Nombre_Fichero + "\n", this.NombreFichero);
            
        //    //sTexto = string.Format(Resources.TextosProceso.Email_Texto_Nombre_Fichero + "\n", this.NombreFichero);
        //    sTexto += string.Format(Resources.TextosProceso.Email_Texto_Registros_Procesados_Correctamente_2Param + "\n", this.NumeroLineasArchivo - this.NumeroProcesadosKO, this.NumeroLineasFueraPeriodo);            

        //    if (this.Servidor_SMTP != "" && this.Email_aviso_OK!= "")
        //    {
        //        SendMail(Servidor_SMTP, SMTP_User, SMTP_Password, SMTP_Port, Email_aviso_OK, Remitente_Email_aviso, "El prodeso de la interfase ha ido OK", sTexto);
        //    }

        //}
        #endregion
        
    }
    
    public class ErrorInfo
    {
        public string ErrorDescription;
        public string ErrorSource;

        public ErrorInfo()
        {
            ErrorDescription = ""; ErrorSource = "";
        }
        public ErrorInfo(string Descripcion, string Source)
        {
            ErrorDescription = Descripcion; ErrorSource = Source;
        }
    }

    
}
